﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using ST.Buz.Base;
using ST.Buz.Base.Entity;
using ST.Common.Util;
using ST.Common.Util.Model;
using System;
using System.Collections.Generic;
using Microsoft.Data.SqlClient;
using System.Linq;

namespace ST.Buz.Service
{
	public partial interface IServiceSysDept
	{
		/// <summary>
		/// 获取指定部门及其所有下级部门的树节点数据
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		List<TreeItem> GetChildrenTreeData(int id);

		/// <summary>
		/// 获取指定单位下的部门或指定部门的下属部门
		/// </summary>
		/// <returns></returns>
		List<Sys_Dept> GetList(int orgid, int deptid, UserSession sessionCurrent);

		/// <summary>
		/// 删除部门
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		bool Delete(int id, UserSession sessionCurrent);

		/// <summary>
		/// 获取自身及所有下级节点ID
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		List<int> GetChildren(int id);

		/// <summary>
		/// 根据id获取详细信息
		/// </summary>
		Sys_Dept GetViewDetail(int id, UserSession sessionCurrent);

		/// <summary>
		/// 根据id获取详细信息
		/// </summary>
		Sys_Dept GetEditDetail(int id, UserSession sessionCurrent);

		/// <summary>
		/// 新增或修改信息
		/// </summary>
		/// <param name="model"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		int AddOrUpdate(Sys_Dept model, UserSession sessionCurrent);

		/// <summary>
		/// 修改父节点
		/// </summary>
		bool UpdateParent(int id, int parentID, UserSession sessionCurrent);

		/// <summary>
		/// 修改排序
		/// </summary>
		bool UpdateOrder(SortItem[] items, UserSession sessionCurrent);
	}

	public partial class ServiceSysDept
	{
		private readonly IServiceSysLog serviceSysLog;

		public ServiceSysDept(BuzContext ctx,
			IServiceSysLog _serviceSysLog,
			ILogger<ServiceSysDept> log)
		{
			serviceSysLog = _serviceSysLog;
			context = ctx;
			logger = log;
		}

		/// <summary>
		/// 获取指定部门及其所有下级部门的树节点数据
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public List<TreeItem> GetChildrenTreeData(int id)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// 获取全部部门的树节点数据
		/// </summary>
		/// <returns></returns>
		public List<TreeItem> GetTreeData()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// 获取指定单位下的部门或指定部门的下属部门
		/// </summary>
		/// <returns></returns>
		public List<Sys_Dept> GetList(int orgid, int deptid, UserSession sessionCurrent)
		{
			try
			{
				SqlParameter[] parameters = new SqlParameter[]{
					new SqlParameter("@dept_id", deptid),
					new SqlParameter("@org_id", orgid),
					new SqlParameter("@errcode",System.Data.SqlDbType.Int),
					new SqlParameter("@errmsg",System.Data.SqlDbType.NVarChar,200)
				};
				parameters[parameters.Length - 2].Direction = System.Data.ParameterDirection.Output;
				parameters[parameters.Length - 1].Direction = System.Data.ParameterDirection.Output;
				var result = context.ExecuteReader<Sys_Dept>("sp_sys_dept_tree", parameters, System.Data.CommandType.StoredProcedure);
				if ((int)parameters[parameters.Length - 2].Value != 0)
				{
					throw new BuzException(Convert.ToString(parameters[parameters.Length - 1].Value));
				}
				return result;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取部门列表出错");
				throw new BuzException("获取部门列表失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 删除部门
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public bool Delete(int id, UserSession sessionCurrent)
		{
			bool success = false;
			try
			{
				//if (logger.IsEnabled(LogLevel.Debug))
				//{
				//	logger.LogDebug($"参数->id:{id}，state:{state}，remark:{remark}");
				//}
				if (sessionCurrent == null)
				{
					throw new BuzException("用户会话不能为空");
				}

				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						#region 事务具体操作
						DateTime dtNow = DateTime.Now;
						string ip = GetRequestIP();

						if (context.SysDept.Any(m => m.PID == id))
						{
							throw new BuzException("该部门有下级部门，请先删除下级部门后再删除");
						}
						if (context.SysUser.Any(m => m.DeptID == id))
						{
							throw new BuzException("该部门下有员工，请先删除员工后再删除");
						}
						var modelOld = Get(id, true);
						Delete(modelOld);

						serviceSysLog.Add(sessionCurrent, ip, $"删除部门{modelOld.Name}[{modelOld.Code}]信息，原信息：", modelOld, dtNow);
						#endregion

						trans.Commit();
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}

				success = true;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "删除部门出错");
				throw new BuzException("删除部门失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return success;
		}

		/// <summary>
		/// 获取自身及所有下级节点ID
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		public List<int> GetChildren(int id)
		{
			if (id <= 0)
			{
				return null;
			}
			try
			{
				var children = context.ExecuteReader<TreeIdentity>(
						"sp_sys_get_tree_children",
						new SqlParameter[] { new SqlParameter("@id", id), new SqlParameter("@table_name", "Sys_Dept") }
					);
				if (children.Count == 0)
				{
					return null;
				}
				List<int> lstTree = new List<int>();
				foreach (var c in children)
				{
					lstTree.Add(c.ID);
				}
				return lstTree;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取下级节点出错");
				throw new BuzException("获取下级节点失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 获取查看时的详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public Sys_Dept GetViewDetail(int id, UserSession sessionCurrent)
		{
			Sys_Dept model = null;
			try
			{
				model = (from c in context.SysDept
						 join p in context.SysDept on c.PID equals p.ID into all
						 from a in all.DefaultIfEmpty()
						 join o in context.SysOrganization on c.OrgID equals o.ID into cotmp
						 from co in cotmp.DefaultIfEmpty()
						 where c.ID == id
						 select new Sys_Dept()
						 {
							 ID = c.ID,
							 AddDate = c.AddDate,
							 AddManID = c.AddManID,
							 AddManName = c.AddManName,
							 Code = c.Code,
							 Name = c.Name,
							 OrgID = c.OrgID,
							 PID = c.PID,
							 PName = a.Name,
							 PYCode = c.PYCode,
							 Reserved = c.Reserved,
							 Sort = c.Sort,
							 Visible = c.Visible,
							 OrgName = co.Name
						 }).SingleOrDefault();
				if (model == null)
				{
					throw new BuzException("参数有误");
				}
			}
			catch (ArgumentException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "获取对象信息出错");
				throw new BuzException("获取对象信息失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			return model;
		}

		/// <summary>
		/// 获取编辑时的详细信息
		/// </summary>
		/// <param name="id"></param>
		/// <param name="sessionCurrent"></param>
		/// <returns></returns>
		public Sys_Dept GetEditDetail(int id, UserSession sessionCurrent)
		{
			return GetViewDetail(id, sessionCurrent);
		}

		/// <summary>
		/// 新增或修改信息
		/// </summary>
		public int AddOrUpdate(Sys_Dept model, UserSession sessionCurrent)
		{
			try
			{
				if (model == null)
				{
					throw new BuzException("参数不能为空");
				}
				if (model.ID > 0)
				{
					Update(model);
				}
				else
				{
					model.AddDate = DateTime.Now;
					model.AddManID = sessionCurrent.UserID;
					model.AddManName = sessionCurrent.UserName;
					model.Visible = true;

					model.ID = Add(model);
				}
				return model.ID;
			}
			catch (BuzException ex)
			{
				throw ex;
			}
			catch (DbUpdateException ex)
			{
				logger.LogError(ex.InnerException ?? ex, "保存对象信息出错");
				throw new BuzException("数据库保存失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "保存对象信息出错");
				throw new BuzException("保存失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 修改父节点
		/// </summary>
		public bool UpdateParent(int id, int parentID, UserSession sessionCurrent)
		{
			try
			{
				if (id <= 0)
				{
					throw new BuzException("参数不能为空");
				}
				var modelOld = context.SysDept.SingleOrDefault(m => m.ID == id);
				if (modelOld == null)
				{
					throw new BuzException("未找到相关记录");
				}
				if (parentID > 0)
				{
					List<int> lstChildren = GetChildren(id);
					if (lstChildren == null || lstChildren.Contains(parentID))
					{
						throw new BuzException("上级不存在或上级选择有误");
					}
				}
				modelOld.PID = parentID;
				context.SaveChanges();

				return true;
			}
			catch (BuzException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				throw new BuzException(ex.Message, ex);
			}
		}

		/// <summary>
		/// 修改排序
		/// </summary>
		public bool UpdateOrder(SortItem[] items, UserSession sessionCurrent)
		{
			try
			{
				if (items == null || items.Length == 0)
				{
					throw new BuzException("参数不能为空");
				}
				using (var trans = context.Database.BeginTransaction())
				{
					try
					{
						foreach (SortItem item in items)
						{
							var entity = context.SysDept.Attach(new Sys_Dept()
							{
								ID = item.id,
								Sort = item.order
							});
							entity.Property("Sort").IsModified = true;
							context.SaveChanges();
						}
						trans.Commit();

						return true;
					}
					catch (Exception ex)
					{
						trans.Rollback();
						throw ex.InnerException ?? ex;
					}
				}
			}
			catch (BuzException ex)
			{
				logger.LogError(ex.InnerException ?? ex, "更新出错");
				throw ex;
			}
			catch (DbUpdateException ex)
			{
				logger.LogError(ex.InnerException ?? ex, "更新出错");
				throw new BuzException("更新失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
			catch (ArgumentException ex)
			{
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, "更新出错");
				throw new BuzException("更新失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}
	}
}